/**
 * JAVACC DEMO 1.0
 */
package com.apache.audit.service.plugins;

import java.util.Map;

import org.apache.commons.collections.map.CaseInsensitiveMap;

import com.apache.api.manager.PluginConnector;
import com.apache.api.vo.ParamsVo;
import com.apache.api.vo.ResultEntity;
import com.apache.audit.entity.LogModel;
import com.apache.audit.entity.LogOperation;
import com.apache.audit.entity.LogOperationDetail;
import com.apache.audit.manager.LogOperationDetailManager;
import com.apache.audit.manager.LogOperationManager;
import com.apache.audit.server.LoggerSaveHelper;
import com.apache.cache.util.Validator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * description:  添加操作日志插件
 *
 */
public class LogOperationSavePlugin implements PluginConnector {

	private Logger log = LoggerFactory.getLogger(LogOperationSavePlugin.class);

	private LoggerSaveHelper helper;

	private LogOperationDetailManager logOperationDetailManager;

	private LogOperationManager logOperationManager;

	/**
	 * TODO 添加操作日志插件<br>
	 * 参数说明：<br>
	 * log_userEname:操作用户账号；<br>
	 * logType:日志类型<br>
	 * logOperationType：日志操作类型（限登录或退出用login/logout）<br>
	 * log_returnValue:执行结果<br>
	 * logIp：操作IP地址<br>
	 * logClassName：操作模型名<br>
	 * 模型属性与值
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public Object execute(ParamsVo vo) throws Exception {
		ResultEntity result = new ResultEntity();
		try {
			String logOperationType = String.valueOf(vo.getParams("logOperationType"));//日志操作类型
			String logClassName = String.valueOf(vo.getParams("logClassName"));
			LogModel model = getLoggerSaveHelper().getLogModel(logClassName.trim());
			if (Validator.isEmpty(model)) {
				result.setResult("false");
				result.setMessage("没有找到匹配的数据模型，暂时不添加日志信息！");
				log.warn("没有找到匹配的数据模型，暂时不添加日志信息！");
				return result;
			}
			LogOperation operation = new LogOperation();
			String userEname = String.valueOf(vo.getParams("log_userEname"));
			operation.setModelId(model.getModelId());
			operation.setCreateUser(userEname);
			operation.setCreatedTime(System.currentTimeMillis());
			operation.setLogIp(String.valueOf(vo.getParams("logIp")));
			if (Validator.isNull(logOperationType)) {
				String logType = String.valueOf(vo.getParams("logType"));
				if ("save".equals(logType)) {
					operation.setLogType("添加");
				} else if ("edit".equals(logType)) {
					operation.setLogType("更新");
				} else if ("del".equals(logType)) {
					operation.setLogType("删除");
				}
				operation = getLoggerSaveHelper().getUserByEname(operation);
				if ("del".equals(logType)) {
					getLoggerSaveHelper().logDeleteInfo(String.valueOf(vo.getParams("infoId")), operation);
				} else {
					CaseInsensitiveMap cMap = new CaseInsensitiveMap();
					Map beanMap = vo.getParams();
					cMap.putAll(beanMap);
					getLoggerSaveHelper().logSave(operation, cMap);
				}
			} else if ("login".equalsIgnoreCase(logOperationType) || "logout".equalsIgnoreCase(logOperationType)) {//登录日志
				operation.setLogType("登录");
				if ("logout".equalsIgnoreCase(logOperationType))
					operation.setLogType("退出");
				operation = getLoggerSaveHelper().getUserByEname(operation);
				loginInfo(operation);
			} else {//业务日志操作
				CaseInsensitiveMap cMap = new CaseInsensitiveMap();
				Map beanMap = vo.getParams();
				cMap.putAll(beanMap);
				operation.setLogType("其他");
				operation = getLoggerSaveHelper().getUserByEname(operation);
				getLoggerSaveHelper().logSave(operation, cMap);
			}
		} catch (Exception e) {
			result.setResult("false");
			log.error("添加日志信息失败 ", e);
			result.setMessage("添加日志信息失败 ！");
		}
		return result;
	}

	/**
	 * description:   记录登录/ 退出日志
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void loginInfo(LogOperation operation) {
		ParamsVo vo = new ParamsVo();
		vo.setObj(operation);
		String logId = logOperationManager.saveInfo(vo);
		if (Validator.isNotNull(logId)) {
			LogOperationDetail detail = new LogOperationDetail();
			detail.setDetailId(Validator.generate());
			detail.setPropertyEname("userEname");
			detail.setPropertyName("用户账号");
			detail.setPropertyValue(operation.getCreateUser());
			detail.setLogId(logId);
			vo.setObj(detail);
			logOperationDetailManager.saveInfo(vo);
		}
	}

	private LoggerSaveHelper getLoggerSaveHelper() {
		if (null == helper) {
			helper = LoggerSaveHelper.newIntance();
		}
		return helper;
	}

	public void setLogOperationDetailManager(LogOperationDetailManager logOperationDetailManager) {
		this.logOperationDetailManager = logOperationDetailManager;
	}

	public void setLogOperationManager(LogOperationManager logOperationManager) {
		this.logOperationManager = logOperationManager;
	}
}
